package edu.client.IngenieriaService;

import java.util.Date;
import java.util.List;
import java.util.Set;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

import edu.shared.DTO.ClaseEquipoPatronDTO;
import edu.shared.DTO.ClaseProductoDTO;
import edu.shared.DTO.ComponentePatronDTO;
import edu.shared.DTO.ElementoProductoDTO;
import edu.shared.DTO.EquipoPatronDTO;
import edu.shared.DTO.ListaDeMaterialesDTO;
import edu.shared.DTO.MaterialProductoDTO;
import edu.shared.DTO.MedidaFijaProductoDTO;
import edu.shared.DTO.MedidaVariableEstandarDTO;
import edu.shared.DTO.OrdenFabricacionGeneralDTO;
import edu.shared.DTO.OrdenPedidoDTO;
import edu.shared.DTO.ProductoDTO;
import edu.shared.DTO.ProveedorDTO;
import edu.shared.DTO.RenglonOrdenFabricacionGeneralDTO;
import edu.shared.DTO.RenglonOrdenPedidoDTO;
import edu.shared.DTO.SubclaseEquipoPatronDTO;

@RemoteServiceRelativePath("ingenieria")

public interface IngenieriaService extends RemoteService {

	/**
	 * Método que busca en la base de datos todas las clases de equipo patrón existentes.
	 * @return lista de clases equipo patrón.
	 * @throws IllegalArgumentException
	 */
	List<ClaseEquipoPatronDTO> buscarClasesEquipoPatron() throws IllegalArgumentException;
	
	/**
	 * Método que busca en base de datos todas las subclases de equipo patrón para la clase con el código pasado como parámetro.
	 * @param codigoClaseEquipoPatron: código de la clase de equipo patrón de la que se quieren recuperar sus subclases.
	 * @return lista con las subclases de equipo patrón correspondientes.
	 * @throws IllegalArgumentException
	 */
	List<SubclaseEquipoPatronDTO> buscarSubclasesEquipoPatron(int codigoClaseEquipoPatron) throws IllegalArgumentException;
	
	/**
	 * Método que registra en la base de datos el equipo patrón pasado como parámetro. Si el equipo pertenece a una clase nueva, también se efectúa el registro de
	 * esta última.
	 * @param equipoPatronDTO: equipo patrón que se desea registrar.
	 * @return equipoPatronDTO: si el registro fue exitoso, devuelve el equipoPatronDTO.
	 * 		   null: caso contrario.
	 */
	EquipoPatronDTO registrarEquipoPatron(EquipoPatronDTO equipoPatronDTO);
	
	/**
	 * Método que busca los equipos patrón con el código de clase y subclase especificados.
	 * Si codigoClase = -1, busca todos los equipos patrón existentes.
	 * Si codigoClase =! -1 y codigoSubclase = -1, busca todos los equipos patrón para el código de clase especificado.
	 * @param codigoClase
	 * @param codigoSubclase
	 * @return lista de equipos patrón especificados.
	 * @throws IllegalArgumentException
	 */
	List<EquipoPatronDTO> buscarEquiposPatronUltimaVersion(int codigoClase, int codigoSubclase) throws IllegalArgumentException;
	
	/**
	 * Método que busca el equipo patrón especificado en los parámetros.
	 * @param codigoClase
	 * @param codigoSubclase
	 * @param plano
	 * @param version
	 * @return el equipo patrón especificado.
	 * @throws IllegalArgumentException
	 */
	EquipoPatronDTO buscarEquipoPatron(int codigoClase, int codigoSubclase, int plano, String version) throws IllegalArgumentException;
	
	/**
	 * Método que actualiza el equipo patrón pasado como parámetro, en sus atributos "descripción técnica", "punto de pedido" y "lote".
	 * @param equipoPatronDTO
	 * @return true: si la actualización fue exitosa.
	 * 		   false: caso contrario.
	 */
	Boolean actualizarEquipoPatron(EquipoPatronDTO equipoPatronDTO);
	
	List<EquipoPatronDTO> buscarEquiposPatron() throws IllegalArgumentException;
	
	List<EquipoPatronDTO> buscarPlanosEquipoPatron(int codigoClaseEquipoPatron, int codigoSubclaseEquipoPatron) throws IllegalArgumentException;
	
	List<ComponentePatronDTO> buscarComponentesPatron(int codigoClaseEquipoPatron, int codigoSubclaseEquipoPatron) throws IllegalArgumentException;
	
	List<ComponentePatronDTO> buscarPlanosComponentePatron(int codigoClaseEquipoPatron, int codigoSubclaseEquipoPatron, int codigoComponente, int codigoSubcomponente) throws IllegalArgumentException;
	
	List<ComponentePatronDTO> buscarComponentesPatron() throws IllegalArgumentException;
	
	List<ComponentePatronDTO> buscarComponentesPatronEnAlmacen();
	
	String buscarUltimaVersionEquipoPatron(EquipoPatronDTO equipoPatronDTO) throws IllegalArgumentException;
	
	
	/**
	 * Método que busca en la base de datos todas las clases de producto cargadas.
	 * @return List<ClaseProductoDTO>. Retorna una lista con las clases de producto cargadas en la base de datos.
	 */
	List<ClaseProductoDTO> buscarClasesProducto();
	
	
	/**
	 * Método que busca en la base de datos todos los elementos de productos pertenecientes a una clase.
	 * @param codigoClase. Código de clase al que perteneces los elementos retornados.
	 * @return List<ElementoProductoDTO>. Retorna una lista con los elementos de producto que perteneces al código de clase
	 * pasado como parámetro.
	 */
	List<ElementoProductoDTO> buscarElementosProducto(int codigoClase);
	
	
	List<MaterialProductoDTO> buscarMaterialesProducto();
	
	
	/**
	 * Método que busca en la base de datos todas las medidas fijas de producto cargadas.
	 * @return List<MedidaFijaProductoDTO>. Retorna una lista con todas las medidas fijas cargadas en la bae de datos.
	 */
	List<MedidaFijaProductoDTO> buscarMedidasFijaProducto();

	/**
	 * Método que busca un proveedor en la base de datos.
	 * @param nombre. Nombre del proveedor a buscar.
	 * @return ProveedorDTO. Retorna el proveedor que tiene el nombre pasado como parámetro.
	 */
	ProveedorDTO buscarProveedor(String nombre);
	
	
	/**
	 * Método que registra o actualiza un producto en la base de datos.
	 * @param producto. Producto a guardar o actualizar.
	 * @return Integer. Retorna el id del producto guardado.
	 * @throws Exception. Lanza excepciones que tendrán un mensaje particular dependiendo del origen
	 * del problema.
	 */
	Integer registrarProducto(ProductoDTO producto) throws Exception;
	
	
	/**
	 * Método que registra las medidas variables estándar de un producto en la base de datos.
	 * @param idProducto. id del roducto al que pertenecen las medidas.
	 * @param medidas. Lista de medidas variables estándar a registrar.
	 * @return Boolean. Retorna true si el proceso de guardado fue exitoso.
	 * @throws Exception. En caso de que el proceso de guardado no sea exitosos, se lanza una excepción detallando el 
	 * origen del error.
	 */
	Boolean registrarMedidasVariablesEstandar(int idProducto, List<MedidaVariableEstandarDTO> medidas) throws Exception;
	
	
	/**
	 * Método que guarda los proveedores de un producto en la base de datos.
	 * @param idProducto. id del producto que los proveedores proveen.
	 * @param proveedores. Lista de proveedores que proveen el producto.
	 * @return Boolean. Retorna true si el proceso de guardado fue exitoso.
	 * @throws Exception. En caso de que el proceso de guardado no sea exitoso, se lanza una excepción detallando el
	 * origen del error.
	 */
	Boolean registrarProveedorDeProducto(int idProducto, List<ProveedorDTO> proveedores) throws Exception;
	
	
	/**
	 * Método que busca todos los productos cargados en la base de datos.
	 * @return List<ProductoDTO>. Retorna una lista con todos los productos cargados.
	 */
	List<ProductoDTO> buscarProductos();
	
	
	/**
	 * Método que busca en la base de datos un producto que cumpla con la clase, elemento y material especificados.
	 * @param codigoClase. Código de clase del producto buscado.
	 * @param codigoElemento. Código de elemento del producto buscado.
	 * @param codigoMaterial. Código de material del prodcuto buscado.
	 * @return List<ProductoDTO>. Retorna una lista con todos los productos que cumplen con los parámetros especificados.
	 */
	List<ProductoDTO> buscarProductos(int codigoClase, int codigoElemento, int codigoMaterial);
	
	
	/**
	 * Método que busca en la base de datos todos los datos de un proveedor.
	 * @param nombre. Nombre del proveedor buscado.
	 * @return ProveedorDTO. Retorna el proveedor que tiene el nombre pasado como parámetro.
	 */
	ProveedorDTO buscarProveedorCompleto(String nombre);
	
	
	/**
	 * Método que busca en la base de datos todos los proveedores que proveen un determinado producto.
	 * @param idProducto. id del producto para el cual se buscan sus proveedores.
	 * @return List<ProductoDTO>. Retorna una lista con todos los proveedores que proveen el producto que tiene el id pasado
	 * como parámetro.
	 */
	List<ProveedorDTO> buscarProveedores(int idProducto);
	
	/**
	 * Método que elimina un producto de la base de datos. (baja lógica)
	 * @param idProducto. id del producto que se pretende dar de baja.
	 * @return Boolean. Si el proceso de guardado fue exitoso, retorna true.
	 * @throws Exception. Si el proceso de guardado no fue exitoso, se lanza una excepción detallando el origen del error.
	 */
	Boolean eliminarProducto(int idProducto) throws Exception;

	/** Método que registra un nuevo plano o una nueva versión para un equipo patrón.
	 * 
	 * @param equipoPatronBase
	 * @return el nuevo equipo patrón
	 */
	EquipoPatronDTO registrarEquipoPatronNuevoPlanoOVersion(EquipoPatronDTO equipoPatronBase);
	
	
	/**
	 * Método que buscan en la base de datos todas las órdenes de pedido que cumplen con los parámetros de entrada.
	 * @param numeroOrden. Número de la orden de pedido. Si se envía un cero, no se filtrará por esta propiedad.
	 * @param nombreCliente. Nombre del cliente al que pertenece la orden de pedido. Si se pasa la cadena vacía, no se filtrará por esta propiedad.
	 * @return List<OrdenPedidoDTO>. Retorna una lista de órdenes de pedido que cumplen con los parámetros de entrada.
	 */
	List<OrdenPedidoDTO> buscarOrdenPedido(int numeroOrden, String nombreCliente);

	/**
	 * Método que coloca como inactivo al equipo patrón con el código pasado.
	 * @param codigoEquipoSeleccionado
	 * @return true, si éxito
	 * 		   false, caso contrario
	 */
	boolean eliminarEquipoPatron(String codigoEquipoSeleccionado);

	/**
	 * Método que registra el componente patrón pasado como parámetro, incluyéndolo también en la lista de materiales de su equipo contenedor
	 * @param componente
	 * @return el componente registrado: si hubo éxito
	 * 		   null: fracaso
	 */
	ComponentePatronDTO registrarComponentePatron(ComponentePatronDTO componente);
	
	/**
	 * Método que busca los renglones de la orden de pedido pasada como parámetro
	 * @param numeroOrden. Es el número de orden de pedido para la cual se quieren buscar sus renglones.
	 * @return List<RenglonOrdenPedido>. Retorna una lista con los renglones de la orden de pedido.
	 */
	List<RenglonOrdenPedidoDTO> buscarRenglonesOrdenPedido(int numeroOrden);

	List<ComponentePatronDTO> buscarComponentesPatronUltimaVersion(int codigoClase, int codigoSubclase, int codigoComponente, int codigoSubcomponente) throws IllegalArgumentException;
	
	/**
	 * Método que registra una orden de fabricación en la base de datos.
	 * @param ordenFabricacionDTO. Es la orden de fabricación a registrar.
	 * @throws Exception. En caso de que se producto algún error en el proceso de registración, se lanza una excepción con el mensaje correspondiente.
	 */
	Boolean registrarOrdenFabricacion(OrdenFabricacionGeneralDTO ordenFabricacionDTO) throws Exception;

	List<EquipoPatronDTO> buscarPlanosEquipoPatronActivosEInactivos(int codigoClase, int codigoSubclase);

	boolean eliminarVersionEquipoPatron(String codigoVersionAnterior);
	
	/**
	 * Método que busca en la base de datos todas las órdenes de fabricación que cumplen con los parámetros de filtrado.
	 * @param estado. Es el estado de la lista de fabricación.
	 * @param fechaEstimadaInicio. Es la fecha estimada de inicio de la orden de fabricación.
	 * @param fechaEstimadaFinalizacion. Es la fecha estimada de finalización de la orden de fabricaicon.
	 * @return List<OrdenFabricacionGeneralDTO>. Retorna una lista con todas las órdenes de fabricación general que tengan como estado 
	 * el pasado como parámetro.
	 */
	List<OrdenFabricacionGeneralDTO> filtrarOrdenesFabricacion(String estado, Date fechaEstimadaInicio, Date fechaEstimadaFinalizacion, boolean pReservasYCompras);
	
	
	/**
	 * Método que busca los renglones de una orden de fabricación general.
	 * @param nroOrdenFabricacion. Es el número de la orden de fabricación general para la cual se quieren buscar sus renglones. 
	 * @return List<RenglonOrdenFabricacionGeneralDTO>. Retorna una lista con los renglones de la orden de fabricación general.
	 */
	Set<RenglonOrdenFabricacionGeneralDTO> buscarRenglonesOrdenFabricacion(int nroOrdenFabricacion);

	List<MedidaFijaProductoDTO> buscarMedidasFijasProducto(int codigoClase, int codigoElemento, int codigoMaterial);

	List<MaterialProductoDTO> buscarMaterialesProducto(int codigoClase, int codigoElemento);


	boolean actualizarComponentePatron(ComponentePatronDTO componentePatron);
	List<EquipoPatronDTO> buscarEquiposPatronEnAlmacen() throws IllegalArgumentException;

	ComponentePatronDTO registrarComponentePatronNuevoPlanoOVersion(ComponentePatronDTO componentePatronBase);
	ComponentePatronDTO buscarComponentePatron(int codigoClase, int codigoSubclase, String version, int codigoComponente, int codigoSubcomponente, int plano) throws IllegalArgumentException;

	ListaDeMaterialesDTO buscarListaMateriales(int idListaMateriales) throws IllegalArgumentException;

	int registrarListaMateriales(ListaDeMaterialesDTO listaDeMaterialesDTO) throws IllegalArgumentException;
	
	public int actualizarCantidadEquipoPatron (int codigoClase, int codigoSubclase, int plano, String version, int cantidadDisponible);
	
	public int actualizarCantidadComponentePatron (int codigoClase, int codigoSubclase, String version, int codigoComponente, int codigoSubcomponente, int plano, int cantidadDisponible);

	boolean eliminarVersionComponentePatron(String codigoVersionAnterior);

	boolean eliminarComponentePatron(String codigoComponenteSeleccionado);

	List<ComponentePatronDTO> buscarComponentesPatronUltimaVersionActivos() throws IllegalArgumentException;

	void actualizarEstadoOrdenFabricacion(OrdenFabricacionGeneralDTO ordenFabricacionDTO) throws Exception;
	
	Boolean registrarInventario(int idProducto, List<MedidaVariableEstandarDTO> medidas);

}
